 using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections.Generic;
using CircularScrollView;
using UI.BankingPanel.Data;

namespace UI.BankingPanel.Components
{
    /// <summary>
    /// 押注数据滚动列表组件
    /// 负责管理49个号码的押注数据显示
    /// 
    /// 主要功能：
    /// 1. 使用增强版循环列表显示49个号码的押注数据
    /// 2. 每个列表项显示4个号码（可配置）
    /// 3. 支持实时数据更新和输入
    /// 4. 提供滚动到指定号码的功能
    /// 5. 自动管理列表项的创建和回收
    /// 
    /// 使用方法：
    /// 1. Initialize() - 初始化组件
    /// 2. SetBetDataList() - 设置数据源
    /// 3. UpdateBetData() - 更新单个号码数据
    /// 4. ScrollToNumber() - 滚动到指定号码
    /// </summary>
    public class C_Bet_ScrollView : MonoBehaviour
    {
        [Header("滚动列表组件")]
        [SerializeField] private EnhancedUICircularScrollView m_ScrollView;
        
        [Header("列表项模板")]
        [SerializeField] private GameObject m_ItemTemplate;
        
        [Header("配置参数")]
        [SerializeField] private int m_NumbersPerItem = 4; // 每个列表项显示的号码数量（按属相分组时会动态调整）
        [SerializeField] private float m_ItemSpacing = 2f; // 列表项间距
        [SerializeField] private int m_PreloadCount = 5; // 预加载数量
        
        // 数据相关
        private List<NumberBetData> m_BetDataList;
        private Action<int, BetDataFieldType, float> m_OnBetDataFieldChanged;
        
        // 组件状态
        private bool m_IsInitialized = false;
        
        #region 初始化方法
        
        /// <summary>
        /// 初始化滚动列表
        /// </summary>
        /// <param name="onBetDataFieldChanged">押注数据字段变化回调</param>
        public void Initialize(Action<int, BetDataFieldType, float> onBetDataFieldChanged = null)
        {
            if (m_IsInitialized) 
            {
                Debug.Log("[C_Bet_ScrollView] 已经初始化过了，跳过");
                return;
            }
            
            Debug.Log("[C_Bet_ScrollView] 开始初始化...");
            m_OnBetDataFieldChanged = onBetDataFieldChanged;
            
            // 自动查找组件
            FindComponents();
            
            // 配置滚动列表
            ConfigureScrollView();
            
            // 初始化滚动列表
            InitializeScrollView();
            
            m_IsInitialized = true;
            Debug.Log("[C_Bet_ScrollView] 初始化完成");
        }
        
        /// <summary>
        /// 自动查找UI组件
        /// </summary>
        private void FindComponents()
        {
            Debug.Log("[C_Bet_ScrollView] 开始查找组件...");
            
            // 查找滚动列表组件
            if (m_ScrollView == null)
            {
                // 先尝试从子对象查找
                m_ScrollView = GetComponentInChildren<EnhancedUICircularScrollView>();
                
                // 如果没找到，尝试添加到当前对象
                if (m_ScrollView == null)
                {
                    Debug.Log("[C_Bet_ScrollView] 未找到EnhancedUICircularScrollView组件，尝试添加到当前对象");
                    m_ScrollView = gameObject.AddComponent<EnhancedUICircularScrollView>();
                }
                
                Debug.Log($"[C_Bet_ScrollView] 滚动列表组件: {(m_ScrollView != null ? "找到/已添加" : "未找到")}");
            }
            
            // 查找列表项模板 - C_Bet_ScrollViewItem和C_Bet_ScrollView都是M_Panel的直接子节点
            if (m_ItemTemplate == null)
            {
                Debug.Log($"[C_Bet_ScrollView] 当前节点: {transform.name}, 父节点: {(transform.parent != null ? transform.parent.name : "null")}");
                
                // 从父节点(M_Panel)查找同级的C_Bet_ScrollViewItem节点
                Transform parent = transform.parent; // M_Panel
                if (parent != null)
                {
                    Transform itemTemplate = parent.Find("C_Bet_ScrollViewItem");
                    if (itemTemplate != null)
                    {
                        m_ItemTemplate = itemTemplate.gameObject;
                        Debug.Log($"[C_Bet_ScrollView] 从父节点找到模板: {itemTemplate.name}");
                    }
                    else
                    {
                        Debug.Log($"[C_Bet_ScrollView] 父节点下未找到C_Bet_ScrollViewItem，父节点子对象列表:");
                        for (int i = 0; i < parent.childCount; i++)
                        {
                            Debug.Log($"  - {parent.GetChild(i).name}");
                        }
                    }
                }
                
                // 如果还是没找到，尝试从根节点按完整路径查找
                if (m_ItemTemplate == null)
                {
                    Transform root = transform.root;
                    Transform itemTemplate = root.Find("M_Panel/C_Bet_ScrollViewItem");
                    if (itemTemplate != null)
                    {
                        m_ItemTemplate = itemTemplate.gameObject;
                        Debug.Log($"[C_Bet_ScrollView] 从根节点找到模板: {itemTemplate.name}");
                    }
                    else
                    {
                        Debug.LogError("[C_Bet_ScrollView] 无法找到C_Bet_ScrollViewItem模板节点！");
                    }
                }
            }
            
            // 验证模板是否有正确的组件
            if (m_ItemTemplate != null)
            {
                var itemComponent = m_ItemTemplate.GetComponent<C_Bet_ScrollViewItem>();
                if (itemComponent == null)
                {
                    // 如果模板没有C_Bet_ScrollViewItem组件，添加一个
                    m_ItemTemplate.AddComponent<C_Bet_ScrollViewItem>();
                    Debug.Log("[C_Bet_ScrollView] 为模板添加了C_Bet_ScrollViewItem组件");
                }
                else
                {
                    Debug.Log("[C_Bet_ScrollView] 模板已有C_Bet_ScrollViewItem组件");
                }
            }
            else
            {
                Debug.LogError("[C_Bet_ScrollView] 模板对象为null，无法继续！");
            }
        }
        
        /// <summary>
        /// 配置滚动列表参数
        /// </summary>
        private void ConfigureScrollView()
        {
            if (m_ScrollView == null) 
            {
                Debug.LogError("[C_Bet_ScrollView] 配置失败：滚动列表组件为null");
                return;
            }
            
            Debug.Log("[C_Bet_ScrollView] 开始配置滚动列表...");
            
            // 基础配置
            m_ScrollView.m_Direction = e_Direction.Vertical;
            m_ScrollView.m_Row = 1; // 单列显示
            m_ScrollView.m_Spacing = m_ItemSpacing;
            m_ScrollView.m_CellGameObject = m_ItemTemplate;
            
            Debug.Log($"[C_Bet_ScrollView] 基础配置完成 - 方向: {m_ScrollView.m_Direction}, 行数: {m_ScrollView.m_Row}, 间距: {m_ScrollView.m_Spacing}");
            Debug.Log($"[C_Bet_ScrollView] 模板对象: {(m_ItemTemplate != null ? m_ItemTemplate.name : "null")}");
            
            // 性能优化配置
            // 注意：m_PoolPreloadCount 是 private 字段，需要在Inspector中手动设置
            // 或者在EnhancedUICircularScrollView的Inspector中设置Pool Preload Count为5
            
            m_ScrollView.SetMaxPoolSize(8);
            m_ScrollView.SetExtremeCacheMode(true); // 使用极致缓存模式
            
            // 动画配置
            m_ScrollView.m_EnableItemAnimation = false;
            m_ScrollView.m_OnlyAnimateFirstTime = true;
            m_ScrollView.m_AnimationDuration = 0.3f;
            m_ScrollView.m_AnimationOffset = 0.05f;
            
            // 隐藏模板
            if (m_ItemTemplate != null)
            {
                m_ItemTemplate.SetActive(false);
                Debug.Log("[C_Bet_ScrollView] 模板对象已隐藏");
            }
            
            Debug.Log("[C_Bet_ScrollView] 滚动列表配置完成");
        }
        
        /// <summary>
        /// 初始化滚动列表
        /// </summary>
        private void InitializeScrollView()
        {
            if (m_ScrollView == null) 
            {
                Debug.LogError("[C_Bet_ScrollView] 初始化失败：滚动列表组件为null");
                return;
            }
            
            Debug.Log("[C_Bet_ScrollView] 开始初始化滚动列表...");
            
            // 初始化滚动列表
            try
            {
                m_ScrollView.Init(OnUpdateListItem);
                Debug.Log("[C_Bet_ScrollView] 滚动列表初始化成功");
            }
            catch (System.Exception e)
            {
                Debug.LogError($"[C_Bet_ScrollView] 滚动列表初始化失败: {e.Message}");
            }
        }
        
        #endregion
        
        #region 数据管理方法
        
        /// <summary>
        /// 设置押注数据列表
        /// </summary>
        /// <param name="betDataList">押注数据列表（49个号码）</param>
        public void SetBetDataList(List<NumberBetData> betDataList)
        {
            Debug.Log($"[C_Bet_ScrollView] 设置数据列表，数据数量: {(betDataList != null ? betDataList.Count : 0)}");
            // 按属相重新组织数据
            m_BetDataList = OrganizeDataByZodiac(betDataList);
            RefreshList();
        }

        /// <summary>
        /// 按属相重新组织数据
        /// </summary>
        /// <param name="originalData">原始数据列表</param>
        /// <returns>按属相组织的数据列表</returns>
        private List<NumberBetData> OrganizeDataByZodiac(List<NumberBetData> originalData)
        {
            if (originalData == null) return null;

            List<NumberBetData> organizedData = new List<NumberBetData>();
            
            // 首先添加本命年49号（第一行）
            var number49Data = originalData.Find(data => data.number == 49);
            if (number49Data != null)
            {
                organizedData.Add(number49Data);
                Debug.Log($"[C_Bet_ScrollView] 添加本命年49号数据到第一行");
            }
            
            // 获取所有属相
            string[] zodiacNames = ZodiacHelper.GetAllZodiacNames();
            
            // 按属相分组，每行显示同一属相的所有号码（排除49号，因为已经单独处理）
            foreach (string zodiac in zodiacNames)
            {
                // 获取当前属相的所有号码
                List<int> zodiacNumbers = ZodiacHelper.GetNumbersByZodiac(zodiac);
                
                // 添加该属相的所有号码数据（横向排列），排除49号
                foreach (int number in zodiacNumbers)
                {
                    if (number != 49) // 排除49号，因为已经单独处理
                    {
                        var numberData = originalData.Find(data => data.number == number);
                        if (numberData != null)
                        {
                            organizedData.Add(numberData);
                        }
                    }
                }
            }
            
            Debug.Log($"[C_Bet_ScrollView] 按属相重新组织数据完成，原始数量: {originalData.Count}, 组织后数量: {organizedData.Count}");
            return organizedData;
        }

        /// <summary>
        /// 获取按属相分组的数据
        /// </summary>
        /// <returns>按属相分组的数据字典，包含本命年特殊行</returns>
        private Dictionary<string, List<NumberBetData>> GetZodiacGroupedData()
        {
            var groupedData = new Dictionary<string, List<NumberBetData>>();
            
            if (m_BetDataList == null) return groupedData;
            
            // 首先添加本命年49号（特殊行）
            var number49Data = m_BetDataList.Find(data => data.number == 49);
            if (number49Data != null)
            {
                groupedData["本命年"] = new List<NumberBetData> { number49Data };
            }
            
            // 获取所有属相
            string[] zodiacNames = ZodiacHelper.GetAllZodiacNames();
            
            // 按属相分组
            foreach (string zodiac in zodiacNames)
            {
                var zodiacData = new List<NumberBetData>();
                
                // 获取当前属相的所有号码
                List<int> zodiacNumbers = ZodiacHelper.GetNumbersByZodiac(zodiac);
                
                // 添加该属相的所有号码数据（排除49号）
                foreach (int number in zodiacNumbers)
                {
                    if (number != 49) // 排除49号，因为已经单独处理
                    {
                        var numberData = m_BetDataList.Find(data => data.number == number);
                        if (numberData != null)
                        {
                            zodiacData.Add(numberData);
                        }
                    }
                }
                
                if (zodiacData.Count > 0)
                {
                    groupedData[zodiac] = zodiacData;
                }
            }
            
            return groupedData;
        }
        
        /// <summary>
        /// 更新单个号码的押注数据
        /// </summary>
        /// <param name="numberIndex">号码索引（0-48）</param>
        /// <param name="betData">押注数据</param>
        public void UpdateBetData(int numberIndex, NumberBetData betData)
        {
            if (m_BetDataList == null || numberIndex < 0 || numberIndex >= m_BetDataList.Count)
                return;
            
            m_BetDataList[numberIndex] = betData;
            
            // 计算对应的列表项索引
            int itemIndex = numberIndex / m_NumbersPerItem + 1; // 索引从1开始
            
            // 更新对应的列表项
            if (m_ScrollView != null)
            {
                m_ScrollView.UpdateCell(itemIndex);
            }
        }
        
        /// <summary>
        /// 刷新整个列表
        /// </summary>
        public void RefreshList()
        {
            if (!m_IsInitialized || m_ScrollView == null || m_BetDataList == null)
            {
                
                return;
            }
            
            // 按属相分组，包含本命年特殊行（第一行）+ 12个属相行
            var groupedData = GetZodiacGroupedData();
            int itemCount = groupedData.Count; // 1个本命年行 + 12个属相行 = 13行
            
            
            // 显示列表
            m_ScrollView.ShowList(itemCount);
        }
        
        /// <summary>
        /// 滚动到指定号码
        /// </summary>
        /// <param name="numberIndex">号码索引（0-48）</param>
        /// <param name="duration">滚动动画时间</param>
        public void ScrollToNumber(int numberIndex, float duration = 0.3f)
        {
            if (m_ScrollView == null || numberIndex < 0 || numberIndex >= 49)
                return;
            
            // 计算对应的列表项索引
            int itemIndex = numberIndex / m_NumbersPerItem + 1; // 索引从1开始
            
            // 滚动到指定项
            m_ScrollView.ScrollToIndex(itemIndex, duration);
        }
        
        #endregion
        
        #region 列表项更新回调
        
        /// <summary>
        /// 列表项更新回调
        /// </summary>
        /// <param name="itemObject">列表项GameObject</param>
        /// <param name="itemIndex">列表项索引（从1开始）</param>
        private void OnUpdateListItem(GameObject itemObject, int itemIndex)
        {
            Debug.Log($"[C_Bet_ScrollView] 更新列表项 - 对象: {(itemObject != null ? itemObject.name : "null")}, 索引: {itemIndex}");
            
            if (itemObject == null || m_BetDataList == null)
            {
                Debug.LogWarning($"[C_Bet_ScrollView] 更新列表项失败 - 对象为null: {itemObject == null}, 数据为null: {m_BetDataList == null}");
                return;
            }
            
            // 获取列表项组件
            C_Bet_ScrollViewItem itemComponent = itemObject.GetComponent<C_Bet_ScrollViewItem>();
            if (itemComponent == null)
            {
                itemComponent = itemObject.AddComponent<C_Bet_ScrollViewItem>();
                Debug.Log($"[C_Bet_ScrollView] 为列表项添加了C_Bet_ScrollViewItem组件");
            }
            
            // 按属相分组获取数据
            var groupedData = GetZodiacGroupedData();
            
            // 第一行是本命年特殊行
            if (itemIndex == 1)
            {
                Debug.Log($"[C_Bet_ScrollView] 列表项{itemIndex}是本命年特殊行");
                
                // 获取本命年49号数据
                List<NumberBetData> itemData = new List<NumberBetData>();
                if (groupedData.ContainsKey("本命年"))
                {
                    itemData = groupedData["本命年"];
                    Debug.Log($"[C_Bet_ScrollView] 本命年行的号码数量: {itemData.Count}");
                }
                
                // 更新列表项数据，标记为本命年特殊行
                itemComponent.UpdateItemData(itemData, 0, OnItemBetDataFieldChanged, true); // 最后一个参数表示是本命年行
                
                Debug.Log($"[C_Bet_ScrollView] 本命年列表项{itemIndex}更新完成");
            }
            else
            {
                // 其他行是属相行
                string[] zodiacNames = ZodiacHelper.GetAllZodiacNames();
                int zodiacIndex = itemIndex - 2; // 减去本命年行，转换为从0开始的索引
                
                if (zodiacIndex >= 0 && zodiacIndex < zodiacNames.Length)
                {
                    string currentZodiac = zodiacNames[zodiacIndex];
                    Debug.Log($"[C_Bet_ScrollView] 列表项{itemIndex}对应属相: {currentZodiac}");
                    
                    // 获取该属相的所有号码数据
                    List<NumberBetData> itemData = new List<NumberBetData>();
                    if (groupedData.ContainsKey(currentZodiac))
                    {
                        itemData = groupedData[currentZodiac];
                        Debug.Log($"[C_Bet_ScrollView] 属相{currentZodiac}的号码数量: {itemData.Count}");
                    }
                    
                    // 计算起始索引（用于回调时的数据定位）
                    int startIndex = 1; // 本命年49号占用索引0
                    for (int i = 0; i < zodiacIndex; i++)
                    {
                        if (i < zodiacNames.Length && groupedData.ContainsKey(zodiacNames[i]))
                        {
                            startIndex += groupedData[zodiacNames[i]].Count;
                        }
                    }
                    
                    Debug.Log($"[C_Bet_ScrollView] 准备更新列表项数据，属相: {currentZodiac}, 数据数量: {itemData.Count}, 起始索引: {startIndex}");
                    
                    // 更新列表项数据
                    itemComponent.UpdateItemData(itemData, startIndex, OnItemBetDataFieldChanged, false); // 最后一个参数表示不是本命年行
                    
                    Debug.Log($"[C_Bet_ScrollView] 列表项{itemIndex}更新完成");
                }
                else
                {
                    Debug.LogWarning($"[C_Bet_ScrollView] 列表项索引超出范围: {itemIndex}");
                }
            }
        }
        
        /// <summary>
        /// 列表项内押注数据字段变化回调
        /// </summary>
        /// <param name="numberId">号码ID</param>
        /// <param name="fieldType">字段类型</param>
        /// <param name="newValue">新值</param>
        private void OnItemBetDataFieldChanged(int numberId, BetDataFieldType fieldType, float newValue)
        {
            Debug.Log($"[C_Bet_ScrollView] 接收到字段变化: 号码{numberId}, 字段{fieldType}, 值{newValue}");
            
            // 触发外部回调，直接传递给上层处理
            m_OnBetDataFieldChanged?.Invoke(numberId, fieldType, newValue);
        }
        
        #endregion
        
        #region 公共接口方法
        
        /// <summary>
        /// 设置押注数据字段变化回调
        /// </summary>
        /// <param name="callback">回调函数</param>
        public void SetBetDataFieldChangedCallback(Action<int, BetDataFieldType, float> callback)
        {
            m_OnBetDataFieldChanged = callback;
        }
        
        /// <summary>
        /// 获取当前押注数据列表
        /// </summary>
        /// <returns>押注数据列表</returns>
        public List<NumberBetData> GetBetDataList()
        {
            return m_BetDataList;
        }
        
        /// <summary>
        /// 清空所有押注数据
        /// </summary>
        public void ClearAllBetData()
        {
            if (m_BetDataList == null) return;
            
            for (int i = 0; i < m_BetDataList.Count; i++)
            {
                var data = m_BetDataList[i];
                data.totalBetAmount = 0;
                data.selfBetAmount = 0;
                data.reportAmount = 0;
                data.riskValue = 0;
                m_BetDataList[i] = data;
            }
            
            RefreshList();
        }
        
        /// <summary>
        /// 设置每个列表项显示的号码数量
        /// </summary>
        /// <param name="numbersPerItem">每项号码数量</param>
        public void SetNumbersPerItem(int numbersPerItem)
        {
            if (numbersPerItem <= 0) return;
            
            m_NumbersPerItem = numbersPerItem;
            RefreshList();
        }
        
        /// <summary>
        /// 设置预加载数量
        /// </summary>
        /// <param name="preloadCount">预加载数量</param>
        public void SetPreloadCount(int preloadCount)
        {
            m_PreloadCount = Mathf.Max(1, preloadCount);
            
            // 注意：由于EnhancedUICircularScrollView的m_PoolPreloadCount是private字段
            // 无法在运行时动态设置，需要在Inspector中手动配置
            Debug.Log($"预加载数量已设置为: {m_PreloadCount}，请在Inspector中同步设置EnhancedUICircularScrollView的Pool Preload Count");
        }
        
        /// <summary>
        /// 获取滚动列表组件
        /// </summary>
        /// <returns>滚动列表组件</returns>
        public EnhancedUICircularScrollView GetScrollView()
        {
            return m_ScrollView;
        }
        
        /// <summary>
        /// 调试信息 - 检查组件状态
        /// </summary>
        public void DebugComponentStatus()
        {
            Debug.Log($"=== C_Bet_ScrollView 组件状态 ===");
            Debug.Log($"ScrollView组件: {(m_ScrollView != null ? "已找到" : "未找到")}");
            Debug.Log($"模板对象: {(m_ItemTemplate != null ? m_ItemTemplate.name : "未找到")}");
            Debug.Log($"是否已初始化: {m_IsInitialized}");
            Debug.Log($"数据列表: {(m_BetDataList != null ? $"已设置({m_BetDataList.Count}项)" : "未设置")}");
            
            if (m_ItemTemplate != null)
            {
                var itemComponent = m_ItemTemplate.GetComponent<C_Bet_ScrollViewItem>();
                Debug.Log($"模板组件: {(itemComponent != null ? "已添加C_Bet_ScrollViewItem" : "缺少C_Bet_ScrollViewItem组件")}");
            }
        }
        
        #endregion
        
        #region Unity生命周期
        
        private void Awake()
        {
            // 在Awake中进行基础初始化
            FindComponents();
        }
        
        private void OnDestroy()
        {
            // 清理资源
            if (m_ScrollView != null)
            {
                m_ScrollView.DisposeAll();
            }
            
            m_OnBetDataFieldChanged = null;
            m_BetDataList = null;
        }
        
        #endregion
    }
}